#include <stdlib.h>
#include "ABMemoryPool.h"

//内存池初始化
void ABMemoryPool_create(ABMemoryPool *pool, unsigned int block_size) {
    pool->block_size = block_size;
    pool->leisure_number = 0;
    pool->leisure_prt = 0;
    pool->practical_ptr = 0;
}


//从内存池申请内存
void *ABMemoryPool_block_malloc(ABMemoryPool *pool) {
    ABMemoryBlock *ret_ptr;

    //从空闲块链表获取内存块
    if (pool->leisure_prt != 0) {
        //只剩下一个
        if (pool->leisure_prt->next_ptr == pool->leisure_prt) {
            ret_ptr = pool->leisure_prt;
        } else {
            ret_ptr = pool->leisure_prt->last_ptr;
            pool->leisure_prt->last_ptr = ret_ptr->last_ptr;
            ret_ptr->last_ptr->next_ptr = pool->leisure_prt;
        }
        pool->leisure_number--;
    } else {

        //向系统申请
        ret_ptr = malloc(sizeof(ABMemoryBlock) + pool->block_size);
        if (ret_ptr == 0)
            return 0;
    }

    //添加到使用块链表
    if (pool->practical_ptr != 0) {
        pool->practical_ptr->last_ptr->next_ptr = ret_ptr;
        ret_ptr->last_ptr = pool->practical_ptr->last_ptr;
        pool->practical_ptr->last_ptr = ret_ptr;
        ret_ptr->next_ptr = pool->practical_ptr;
        pool->practical_ptr = ret_ptr;
    } else {
        pool->practical_ptr = ret_ptr;
        ret_ptr->last_ptr = ret_ptr;
        ret_ptr->next_ptr = ret_ptr;
    }

    return (((void *) ret_ptr) + sizeof(ABMemoryBlock));
}

//从内存池释放内存
void ABMemoryPool_block_free(ABMemoryPool *pool, void *ptr) {
    if (ptr == 0)
        return;
    ABMemoryBlock *block_ptr;

    //获取内存块地址
    block_ptr = (ABMemoryBlock *) (ptr - sizeof(ABMemoryBlock));

    //从使用块链表去除块
    if (block_ptr == pool->practical_ptr) {
        //只剩下一个
        pool->practical_ptr = 0;
    } else {
        block_ptr->last_ptr->next_ptr = block_ptr->next_ptr;
        block_ptr->next_ptr->last_ptr = block_ptr->last_ptr;
    }

    //添加到空闲列表
    if (pool->leisure_prt != 0) {
        pool->leisure_prt->last_ptr->next_ptr = block_ptr;
        block_ptr->last_ptr = pool->leisure_prt->last_ptr;
        pool->leisure_prt->last_ptr = block_ptr;
        block_ptr->next_ptr = pool->leisure_prt;
        pool->leisure_prt = block_ptr;
    } else {
        pool->leisure_prt = block_ptr;
        block_ptr->last_ptr = block_ptr;
        block_ptr->next_ptr = block_ptr;
    }
    pool->leisure_number++;
}


//释放空闲的内存块
void ABMemoryPool_free_leisure(ABMemoryPool *pool, unsigned int leisure_max_number) {
    ABMemoryBlock *last_ptr, *block_ptr;
    if (pool->leisure_prt != NULL)
        last_ptr = pool->leisure_prt->last_ptr;
    else
        return;

    while (pool->leisure_number - 1 > leisure_max_number) {
        block_ptr = pool->leisure_prt->next_ptr;
        free(pool->leisure_prt);
        pool->leisure_prt = block_ptr;
        pool->leisure_number--;
    }
    if (leisure_max_number == 0) {
        free(pool->leisure_prt);
        pool->leisure_prt = 0;
        pool->leisure_number--;
    } else if (pool->leisure_number > leisure_max_number) {
        block_ptr = pool->leisure_prt->next_ptr;
        free(pool->leisure_prt);
        pool->leisure_prt = block_ptr;
        pool->leisure_number--;

        pool->leisure_prt->last_ptr = last_ptr;
        last_ptr->next_ptr = pool->leisure_prt;
    }
}


//内存池销毁
void ABMemoryPool_destroy(ABMemoryPool *pool) {
    ABMemoryBlock *block_ptr, *ptr;

    //释放空闲块
    ptr = pool->leisure_prt;
    block_ptr = 0;
    while (block_ptr != ptr) {
        block_ptr = pool->leisure_prt->next_ptr;
        free(pool->leisure_prt);
        pool->leisure_prt = block_ptr;
    }
    pool->leisure_prt = 0;

    //释放使用块
    ptr = pool->practical_ptr;
    block_ptr = 0;
    while (block_ptr != ptr) {
        block_ptr = pool->practical_ptr->next_ptr;
        free(pool->practical_ptr);
        pool->practical_ptr = block_ptr;
    }
    pool->practical_ptr = 0;
}

